On x86, Xen does not claim any serial port unless the user
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 3 Aug 2005 14:44:19 +0000 (14:44 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 3 Aug 2005 14:44:19 +0000 (14:44 +0000)
explicitly specifies a 'com1=' or 'com2=' configuration
string. This prevents users from being surprised when Xen
stops domain0 from accessing serial port registers.

On ia64 we still allow serial ports to get automatically
configured and locked down even if no 'com1' is specified
on the command line. This maintains the default preferred
by the IA64 developers.

Also, the method for specifying 'use existing baud rate'
has changed. Instead of specifying com1=0, you must now
specify e.g., com1=auto

Signed-off-by: Keir Fraser <keir@xensource.com>
docs/src/user.tex
xen/arch/ia64/xensetup.c
xen/drivers/char/ns16550.c
xen/include/xen/serial.h

index 32c0decde7bc3d93e9b12b7cf7c1209311f63003..da41a813dc552ac5f9981c94602527cdb9198263 100644 (file)
@@ -1709,8 +1709,11 @@ editing \path{grub.conf}.
  For example: `com1=9600, 8n1, 0x408, 5' maps COM1 to a
  9600-baud port, 8 data bits, no parity, 1 stop bit,
  I/O port base 0x408, IRQ 5.
- If the I/O base and IRQ are standard (com1:0x3f8,4;
- com2:0x2f8,3) then they need not be specified. 
+ If some configuration options are standard (e.g., I/O base and IRQ),
+ then only a prefix of the full configuration string need be
+ specified. If the baud rate is pre-configured (e.g., by the
+ bootloader) then you can specify `auto' in place of a numeric baud
+ rate. 
 
 \item [console=$<$specifier list$>$ ] 
  Specify the destination for Xen console I/O.
index 7bcc2e7b824f1d2f973638b10eb69994bd789cd4..88e9fc1c19dafe095b06e034fae69f44a8036127 100644 (file)
@@ -131,12 +131,14 @@ void early_cmdline_parse(char **cmdline_p)
 }
 
 struct ns16550_defaults ns16550_com1 = {
+    .baud      = BAUD_AUTO,
     .data_bits = 8,
     .parity    = 'n',
     .stop_bits = 1
 };
 
 struct ns16550_defaults ns16550_com2 = {
+    .baud      = BAUD_AUTO,
     .data_bits = 8,
     .parity    = 'n',
     .stop_bits = 1
index 3a08bdb5cf265475d383f39477f613af7245274b..3a39c6c426867780e46d4bd9aedd146d972ceeef 100644 (file)
 #include <xen/serial.h>
 #include <asm/io.h>
 
-/* Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
+/*
+ * Configure serial port with a string <baud>,DPS,<io-base>,<irq>.
+ * The tail of the string can be omitted if platform defaults are sufficient.
+ * If the baud rate is pre-configured, perhaps by a bootloader, then 'auto'
+ * can be specified in place of a numeric baud rate.
+ */
 static char opt_com1[30] = "", opt_com2[30] = "";
 string_param("com1", opt_com1);
 string_param("com2", opt_com2);
@@ -154,7 +159,7 @@ static void ns16550_init_preirq(struct serial_port *port)
     ns_write_reg(uart, IER, 0);
 
     /* Line control and baud-rate generator. */
-    if ( uart->baud != 0 )
+    if ( uart->baud != BAUD_AUTO )
     {
         ns_write_reg(uart, LCR, lcr | LCR_DLAB);
         ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */
@@ -244,38 +249,50 @@ static void ns16550_parse_port_config(struct ns16550 *uart, char *conf)
 {
     int baud;
 
+    /* No user-specified configuration? */
     if ( (conf == NULL) || (*conf == '\0') )
-        goto config_parsed;
+    {
+        /* Some platforms may automatically probe the UART configuartion. */
+        if ( uart->baud != 0 )
+            goto config_parsed;
+        return;
+    }
 
-    if ( (baud = simple_strtol(conf, &conf, 10)) != 0 )
+    if ( strncmp(conf, "auto", 4) == 0 )
+    {
+        uart->baud = BAUD_AUTO;
+        conf += 4;
+    }
+    else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 )
         uart->baud = baud;
 
     if ( *conf != ',' )
         goto config_parsed;
     conf++;
 
-    uart->data_bits = simple_strtol(conf, &conf, 10);
+    uart->data_bits = simple_strtoul(conf, &conf, 10);
 
     uart->parity = parse_parity_char(*conf);
     conf++;
 
-    uart->stop_bits = simple_strtol(conf, &conf, 10);
+    uart->stop_bits = simple_strtoul(conf, &conf, 10);
 
     if ( *conf == ',' )
     {
         conf++;
-        uart->io_base = simple_strtol(conf, &conf, 0);
+        uart->io_base = simple_strtoul(conf, &conf, 0);
 
         if ( *conf == ',' )
         {
             conf++;
-            uart->irq = simple_strtol(conf, &conf, 10);
+            uart->irq = simple_strtoul(conf, &conf, 10);
         }
     }
 
  config_parsed:
     /* Sanity checks. */
-    if ( (uart->baud != 0) && ((uart->baud < 1200) || (uart->baud > 115200)) )
+    if ( (uart->baud != BAUD_AUTO) &&
+         ((uart->baud < 1200) || (uart->baud > 115200)) )
         PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
     if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
         PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
index e36e087cef37f96540e83e29cca488587fc2aa8a..28f11f4677268014c7d8c04f0511ab757187379b 100644 (file)
@@ -113,8 +113,9 @@ void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs);
 /*
  * Initialisers for individual uart drivers.
  */
+/* NB. Any default value can be 0 if it is unknown and must be specified. */
 struct ns16550_defaults {
-    int baud;      /* default baud rate; 0 == pre-configured */
+    int baud;      /* default baud rate; BAUD_AUTO == pre-configured */
     int data_bits; /* default data bits (5, 6, 7 or 8) */
     int parity;    /* default parity (n, o, e, m or s) */
     int stop_bits; /* default stop bits (1 or 2) */
@@ -123,6 +124,9 @@ struct ns16550_defaults {
 };
 void ns16550_init(int index, struct ns16550_defaults *defaults);
 
+/* Baud rate was pre-configured before invoking the UART driver. */
+#define BAUD_AUTO (-1)
+
 #endif /* __XEN_SERIAL_H__ */
 
 /*